﻿using System;
using System.Collections.Generic;
using System.Linq;

[Serializable]
public class Product
{
    public string ProductId { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }

    public Product() { } // XML序列化需要无参构造函数

    public Product(string productId, string name, decimal price)
    {
        ProductId = productId;
        Name = name;
        Price = price;
    }

    public override string ToString() => $"商品ID: {ProductId}, 名称: {Name}, 单价: {Price:C}";

    public override bool Equals(object obj) => obj is Product other &&
        ProductId == other.ProductId;

    public override int GetHashCode() => ProductId.GetHashCode();
}

[Serializable]
public class Customer
{
    public string CustomerId { get; set; }
    public string Name { get; set; }

    public Customer() { } // XML序列化需要无参构造函数

    public Customer(string customerId, string name)
    {
        CustomerId = customerId;
        Name = name;
    }

    public override string ToString() => $"客户ID: {CustomerId}, 姓名: {Name}";

    public override bool Equals(object obj) => obj is Customer other &&
        CustomerId == other.CustomerId;

    public override int GetHashCode() => CustomerId.GetHashCode();
}

[Serializable]
public class OrderDetail
{
    public Product Product { get; set; }
    public int Quantity { get; set; }
    public decimal Amount => Product.Price * Quantity;

    public OrderDetail() { } // XML序列化需要无参构造函数

    public OrderDetail(Product product, int quantity)
    {
        Product = product;
        Quantity = quantity;
    }

    public override string ToString() => $"{Product}, 数量: {Quantity}, 小计: {Amount:C}";

    public override bool Equals(object obj) => obj is OrderDetail other &&
        Product.Equals(other.Product);

    public override int GetHashCode() => Product.GetHashCode();
}

[Serializable]
public class Order : IComparable<Order>
{
    public string OrderId { get; set; }
    public Customer Customer { get; set; }
    public DateTime OrderDate { get; set; }
    public List<OrderDetail> Details { get; set; } = new List<OrderDetail>();
    public decimal TotalAmount => Details.Sum(d => d.Amount);

    public Order() { } // XML序列化需要无参构造函数

    public Order(string orderId, Customer customer, DateTime orderDate)
    {
        OrderId = orderId;
        Customer = customer;
        OrderDate = orderDate;
    }

    public void AddDetail(OrderDetail detail)
    {
        if (Details.Any(d => d.Product.ProductId == detail.Product.ProductId))
            throw new ArgumentException("订单中已存在相同的商品");
        Details.Add(detail);
    }

    public void RemoveDetail(Product product)
    {
        var detail = Details.FirstOrDefault(d => d.Product.Equals(product));
        if (detail == null) throw new ArgumentException("订单中不存在指定的商品");
        Details.Remove(detail);
    }

    public override string ToString() =>
        $"订单号: {OrderId}, 客户: {Customer}, 日期: {OrderDate:yyyy-MM-dd}\n" +
        $"明细:\n{string.Join("\n", Details.Select(d => $"  {d}"))}\n" +
        $"总金额: {TotalAmount:C}";

    public override bool Equals(object obj) => obj is Order other &&
        OrderId == other.OrderId;

    public override int GetHashCode() => OrderId.GetHashCode();

    public int CompareTo(Order other) => OrderId.CompareTo(other.OrderId);
}